﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Weblications.Sango.Entities;
using Pixysoft.Weblications.Sango.Mission;
using Pixysoft.Reflection;
using Pixysoft.Framework.Reflection;
using Pixysoft.Framework.Verifications;
using Pixysoft.Weblications.Sango.Formular;
using Pixysoft.Tools;
using Pixysoft.Weblications.Sango.Constant;

namespace Pixysoft.Weblications.Sango.Environment
{
    class MissionHelper
    {
        private static List<Mis_Mainmission> mains = new List<Mis_Mainmission>();

        private static List<Mis_Dailymission> dailies = new List<Mis_Dailymission>();

        public static void initialize()
        {
            mains = SettingHelper.GetNoebe().EntityNoebeCommand.Select<Mis_Mainmission>();
            LoggerHelper.Debug("initialize Mis_Mainmission.count:{0}", mains.Count);

            dailies = SettingHelper.GetNoebe().EntityNoebeCommand.Select<Mis_Dailymission>();
            LoggerHelper.Debug("initialize Mis_Dailymission.count:{0}", dailies.Count);

            // initialize main mission

            foreach (Mis_Mainmission mission in mains)
            {
                if (string.IsNullOrEmpty(mission.Codeclass))
                    continue;

                try
                {
                    IMainMissionHandler handler = (IMainMissionHandler)Activator.CreateInstance(Type.GetType(mission.Codeclass));
                    handler.initialize(mission);
                    MainMissionFactory.register(handler);
                }
                catch
                {
                    throw Exceptions.ExternalException(mission.Codeclass);
                }
            }
        }


        public static Mis_Mainmission getMainMission(long serialcode)
        {
            foreach (Mis_Mainmission main in mains)
            {
                if (main.Serialcode == serialcode)
                    return main;
            }

            throw Exceptions.VerificationFailedException(serialcode);
        }

        public static List<Mis_Mainmission> mainMissions()
        {
            return mains;
        }

        public static List<Mis_Mainmission> getNextMainMissions(long serialcode)
        {
            List<Mis_Mainmission> list = new List<Mis_Mainmission>();

            foreach (Mis_Mainmission main in mains)
            {
                if (main.Parentserialcode == serialcode)
                    list.Add(main);
            }

            return list;
        }



        protected static Mis_Dailymission getDailyMissionByTypeCode(long typecode)
        {
            return getDailyMissionByTypeCode(typecode, MissionFormular.default_dailymission_minlevel);
        }

        public static Mis_Dailymission getDailyMissionByTypeCode(long typecode, long level)
        {
            foreach (Mis_Dailymission daily in dailies)
            {
                if (daily.Missiontypecode != typecode)
                    continue;

                if (daily.Missionlevel != level)
                    continue;

                return daily;
            }

            throw Exceptions.VerificationFailedException(typecode);
        }

        public static List<Mis_Dailymission> dailyMissions()
        {
            return dailies;
        }


        public static List<Mis_Dailymission> initializeDailyMissions()
        {
            List<Mis_Dailymission> list = new List<Mis_Dailymission>();

            List<long> duplicateList = new List<long>();

            Random ran = new Random();

            for (int i = 0; i < MissionFormular.default_max_dailymission; i++)
            {
                do
                {
                    int typecode = (int)Math.Pow(2, (double)ran.Next(0, 6)); // max = 6 -> 2^6=32

                    if (duplicateList.Contains(typecode))
                        continue;

                    duplicateList.Add(typecode);

                    list.Add(getDailyMissionByTypeCode(typecode));

                    break;
                }
                while (true);
            }

            return list;
        }

        internal static Eqm_Equipment trySearchEquipment(long missionTypecode, long level)
        {
            Mis_Dailymission mission = getDailyMissionByTypeCode(missionTypecode, level);
            if (mission.Equipmentserialcode == PlayerFormular.default_number_empty)
                return null;
            return EqmEquipmentHelper.searchBySerialcode(mission.Equipmentserialcode);
        }
    }
}
